//---------------------------------------------------------------------
// Authors: AlexAngelopoulos, Keith Hill, jachymko
//
// Description: Class implementing Get-MountPoint command.
//
// Creation Date: Oct  9, 2006
// Modified Date: Dec 13, 2006
//
//---------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.IO;
using System.Management.Automation;
using System.Runtime.InteropServices;
using System.Text;

namespace Pscx.Commands.FileSystem.Ntfs
{
    using Interop;

    [Cmdlet(VerbsCommon.Get, PscxNouns.MountPoint)]
    [Description("Returns all mount points defined for a specific root path.")]
    [RelatedLinks("Remove-MountPoint")]
    public class GetMountPointCommand : PSCmdlet
    {
        string _volume;

        [AllowNull]
        [AllowEmptyString]
        [Parameter(Position = 0, HelpMessage = "When specified, gets mount points on the specified volume; otherwise, returns mount points on all volumes.")]
        public string Volume
        {
            set { _volume = value; }
            get { return _volume; }
        } 

        protected override void ProcessRecord()
        {
            string volume = Path.GetPathRoot(_volume);
    
            if(string.IsNullOrEmpty(volume))
            {
                EnumerateVolumes();
            }
            else
            {
                volume = ReparsePointHelper.EnsurePathSlash(volume);
                EnumerateVolumeMountPoints(volume);
            }
        }

        void EnumerateVolumes()
        {
            foreach(DriveInfo drive in DriveInfo.GetDrives())
            {
                if(drive.DriveType != DriveType.Fixed)
                    continue;

                EnumerateVolumeMountPoints(drive.RootDirectory.FullName);
            }
        }

        void EnumerateVolumeMountPoints(string volume)
        {
            StringBuilder nameBuffer = new StringBuilder(NativeMethods.MAX_PATH);

            using(SafeFindVolumeMountPointHandle hFind = NativeMethods.FindFirstVolumeMountPoint(volume, nameBuffer, nameBuffer.Capacity))
            {
                if(hFind.IsInvalid)
                    return;

                do
                {
                    string volumeName = string.Empty;
                    string mountPointName = Path.Combine(volume, nameBuffer.ToString());

                    if(NativeMethods.GetVolumeNameForVolumeMountPoint(mountPointName, nameBuffer, nameBuffer.Capacity))
                    {
                        volumeName = nameBuffer.ToString();
                    }

                    WriteObject(new LinkReparsePointInfo(ReparsePointType.MountPoint, mountPointName, volumeName));
                }
                while (NativeMethods.FindNextVolumeMountPoint(hFind, nameBuffer, nameBuffer.Capacity));
            }

        }
    }
}
